/* 
 * File:   MainWindow.cpp
 * Author: loreilei
 * 
 * Created on 27 janvier 2013, 19:52
 */

#include "MainWindow.hpp"

MainWindow::MainWindow() {
    buildUI();    
}

MainWindow::~MainWindow() {
}

void MainWindow::buildUI() {
    
    //Proprités de la fenêtre
    this->setWindowTitle("Steganographer");
    this->setMinimumSize(QSize(800, 600));
    
    //Une barre d'état
    statusBar = new QStatusBar();
    //Une barre de menu
    menuBar = new QMenuBar();
    
    //Un menu
    menuFichier = new QMenu("Fichier");
    QAction *actionQuitter = new QAction("Quitter", menuFichier);
    menuFichier->addAction(actionQuitter);
    connect(actionQuitter, SIGNAL(triggered()), qApp, SLOT(quit()));
    
    //Le widget central
    buildEncodageTab();
    buildDecodageTab();
    
    central = new QTabWidget();
    central->addTab(encodageTab, "Encodage");
    central->addTab(decodageTab, "Decodage");
    
    this->setCentralWidget(central);
    
    menuBar->addMenu(menuFichier);
    
    
    this->setStatusBar(statusBar);
    this->setMenuBar(menuBar);
}

void MainWindow::buildEncodageTab() {
    couvertureImage = NULL;
    couverturePixmap = NULL;
    cacheeImage = NULL;
    cacheePixmap = NULL;
    resultatImage = NULL;
    resultatPixmap = NULL;
    
    encodageTab = new QWidget(this);
    encodageTabLayout = new QGridLayout();
    
    couvertureLabel = new QLabel("Image de couverture : ");
    couvertureChooser = new QPushButton("Choisir une image de couverture");
    connect(couvertureChooser, SIGNAL(clicked()), this, SLOT(chooseCouvertureFile()));
    encodageTabLayout->addWidget(couvertureLabel, 0, 0);
    encodageTabLayout->addWidget(couvertureChooser, 1, 0);
    
    cacheeLabel = new QLabel("Image a cacher : ");
    cacheeChooser = new QPushButton("Choisir une image a cacher");
    connect(cacheeChooser, SIGNAL(clicked()), this, SLOT(chooseCacheeFile()));
    encodageTabLayout->addWidget(cacheeLabel, 0, 1);
    encodageTabLayout->addWidget(cacheeChooser, 1, 1);
    
    resultatLabel = new QLabel("Resultat :");
    nbBitsLabelEncodage = new QLabel("Nombre de bits a utiliser :");
    nbBitsEncodage = new QSpinBox();
    nbBitsEncodage->setMinimum(1);
    nbBitsEncodage->setMaximum(4);
    resultatChooser = new QPushButton("Cacher l'image");
    sauveResultat = NULL;
    connect(resultatChooser, SIGNAL(clicked()), this, SLOT(cacherImage()));
    encodageTabLayout->addWidget(resultatLabel, 0, 2, 1, 2);
    encodageTabLayout->addWidget(nbBitsLabelEncodage, 1, 2);
    encodageTabLayout->addWidget(nbBitsEncodage, 1, 3);
    encodageTabLayout->addWidget(resultatChooser, 2, 2, 1, 2);
    
    
    encodageTab->setLayout(encodageTabLayout);
}

void MainWindow::buildDecodageTab() {
    aDecoderImage = NULL;
    aDecoderPixmap = NULL;
    decodeeImage = NULL;
    decodeePixmap = NULL;
    decodeeResultat = NULL;
    
    decodageTab = new QWidget(this);
    decodageTabLayout = new QGridLayout();
    nbBitsLabelDecodage = new QLabel("Nombre de bits a utiliser :");
    nbBitsDecodage = new QSpinBox();
    nbBitsDecodage->setMinimum(1);
    nbBitsDecodage->setMaximum(4);
    
    aDecoderLabel = new QLabel("Image a decoder : ");
    aDecoderChooser = new QPushButton("Choisir une image a decoder");
    connect(aDecoderChooser, SIGNAL(clicked()), this, SLOT(choosePictureToDecode()));
    decodageTabLayout->addWidget(aDecoderLabel, 0, 0);
    decodageTabLayout->addWidget(aDecoderChooser, 1, 0);

    decodeeLabel = new QLabel("Decodage : ");
    decodeeChooser = new QPushButton("Decoder l'image");
    connect(decodeeChooser, SIGNAL(clicked()), this, SLOT(decodePicture()));
    decodageTabLayout->addWidget(decodeeLabel, 0, 1, 1, 2);
    decodageTabLayout->addWidget(nbBitsLabelDecodage, 1, 1);
    decodageTabLayout->addWidget(nbBitsDecodage, 1, 2);
    decodageTabLayout->addWidget(decodeeChooser, 2, 1, 1, 2);
        
    decodageTab->setLayout(decodageTabLayout);
}

void MainWindow::chooseCouvertureFile() {
    QString filename = QFileDialog::getOpenFileName(this, tr("Choisir une image de couverture"), qApp->applicationFilePath(), tr("Fichiers images (*.png *.jpg *.bmp)"));
    couvertureImage = new QImage(filename);
    couverturePixmap = new QLabel();
    QPixmap temp;
    temp.convertFromImage(*couvertureImage);
    if(temp.width() <= 250) {
        couverturePixmap->setPixmap(temp);
    }
    else {
        couverturePixmap->setPixmap(temp.scaledToWidth(250));
    }
    
    encodageTabLayout->addWidget(couverturePixmap, 3, 0);
}

void MainWindow::chooseCacheeFile() {
    QString filename = QFileDialog::getOpenFileName(this, tr("Choisir une image a cacher"), qApp->applicationFilePath(), tr("Fichiers images (*.png *.jpg *.bmp)"));
    cacheeImage = new QImage(filename);
    cacheePixmap = new QLabel();
    QPixmap temp;
    temp.convertFromImage(*cacheeImage);
    if(temp.width() <= 250) {
        cacheePixmap->setPixmap(temp);
    }
    else {
        cacheePixmap->setPixmap(temp.scaledToWidth(250));
    }
    
    encodageTabLayout->addWidget(cacheePixmap, 3, 1);
}

void MainWindow::cacherImage() {
    QHBoxLayout layout;
    QLabel texte("En cours d'encodage : ");
    layout.addWidget(&texte);
    QProgressBar barre;
    barre.setValue(0);
    barre.setMinimum(0);
    barre.setMaximum(100);
    layout.addWidget(&barre);
    barre.setTextVisible(true);
    if(statusBar->layout() == NULL) {
        statusBar->setLayout(&layout);
    }
    if(couvertureImage != NULL) {
        if(cacheeImage != NULL) {
            if(couvertureImage->size() == cacheeImage->size()) {
                int nb = nbBitsEncodage->value();
                resultatImage = new QImage(*couvertureImage);
                for(int j = 0; j < resultatImage->height(); j++) {
                    for(int i = 0; i < resultatImage->width(); i++) {
                        QColor pixel(resultatImage->pixel(i,j));
                        QColor pixelACacher(cacheeImage->pixel(i,j));
                        
                        int maskCov = (0xFF<<nb);
                        pixel.setRed((pixel.red()&maskCov)|pixelACacher.red()>>(8-nb));
                        pixel.setGreen((pixel.green()&maskCov)|pixelACacher.green()>>(8-nb));
                        pixel.setBlue((pixel.blue()&maskCov)|pixelACacher.blue()>>(8-nb));
                        
                        resultatImage->setPixel(i,j, pixel.rgba());
                        barre.setValue((i*j)/(resultatImage->height()*resultatImage->width())*100);
                    }
                }
                
                resultatPixmap = new QLabel();
                QPixmap temp;
                temp.convertFromImage(*resultatImage);
                if(temp.width() <= 250) {
                    resultatPixmap->setPixmap(temp);
                }
                else {
                    resultatPixmap->setPixmap(temp.scaledToWidth(250));
                }
                
                encodageTabLayout->addWidget(resultatPixmap, 3, 2, 1, 2);
                if(sauveResultat == NULL) {
                    sauveResultat = new QPushButton("Sauver le resultat");
                    encodageTabLayout->addWidget(sauveResultat, 4, 2, 1, 2);
                    connect(sauveResultat, SIGNAL(clicked()), this, SLOT(sauverResultat()));
                }
               
                
            }
            else {
                QMessageBox::critical(this, "Erreur", "Les images selectionnes ne font pas la meme taille.");
            }
        }
        else {
            QMessageBox::critical(this, "Erreur", "Vous n'avez pas choisi d'image a cacher.");
        }
    }
    else {
        QMessageBox::critical(this, "Erreur", "Vous n'avez pas choisi d'image de couverture.");
    }
}

void MainWindow::sauverResultat() {
    QString filename = QFileDialog::getSaveFileName(this, tr("Sauver le resultat"), qApp->applicationFilePath(), tr("Fichiers images (*.png *.jpg *.bmp)"));
    resultatImage->save(filename);
}

void MainWindow::choosePictureToDecode() {
    QString filename = QFileDialog::getOpenFileName(this, tr("Choisir une image a decoder"), qApp->applicationFilePath(), tr("Fichiers images (*.png *.jpg *.bmp)"));
    aDecoderImage = new QImage(filename);
    aDecoderPixmap = new QLabel();
    QPixmap temp;
    temp.convertFromImage(*aDecoderImage);
    if(temp.width() <= 250) {
        aDecoderPixmap->setPixmap(temp);
    }
    else {
        aDecoderPixmap->setPixmap(temp.scaledToWidth(250));
    }
    
    decodageTabLayout->addWidget(aDecoderPixmap, 3, 0);
}

void MainWindow::decodePicture() {
    
    if(aDecoderImage != NULL) {
            int nb = nbBitsDecodage->value();
            decodeeImage = new QImage(*aDecoderImage);
            for(int j = 0; j < aDecoderImage->height(); j++) {
                for(int i = 0; i < aDecoderImage->width(); i++) {
                    QColor pixel(decodeeImage->pixel(i,j));

                    int maskCov = pow(2, nb)-1;
                    pixel.setRed((pixel.red()&maskCov) << (8-nb));
                    pixel.setGreen((pixel.green()&maskCov) << (8-nb));
                    pixel.setBlue((pixel.blue()&maskCov) << (8-nb));

                    decodeeImage->setPixel(i,j, pixel.rgba());
                }
            }

            decodeePixmap = new QLabel();
            QPixmap temp;
            temp.convertFromImage(*decodeeImage);
            if(temp.width() <= 250) {
                decodeePixmap->setPixmap(temp);
            }
            else {
                decodeePixmap->setPixmap(temp.scaledToWidth(250));
            }

            decodageTabLayout->addWidget(decodeePixmap, 3, 1, 1, 2);
            if(decodeeResultat == NULL) {
                decodeeResultat = new QPushButton("Sauver l'image decodee");
                decodageTabLayout->addWidget(decodeeResultat, 4, 1, 1, 2);
                connect(decodeeResultat, SIGNAL(clicked()), this, SLOT(sauverImageDecodee()));
            }
    }
    else {
        QMessageBox::critical(this, "Erreur", "Vous n'avez pas choisi d'image a decoder.");
    }
}

void MainWindow::sauverImageDecodee() {
    QString filename = QFileDialog::getSaveFileName(this, tr("Sauver l'image decodee"), qApp->applicationFilePath(), tr("Fichiers images (*.png *.jpg *.bmp)"));
    decodeeImage->save(filename);
}